﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace IslandInterloper.Engine
{
    public interface ILocation
    {
        double X { get; }
        double Y { get; }
        IHeading ToHeading();
        double DistanceTo(ILocation other);
        double Magnitude { get; }
    }
    internal class Location:ILocation
    {
        private double x;
        public double X
        {
            get
            {
                return x;
            }
            set
            {
                x = value;
            }
        }
        private double y;
        public double Y
        {
            get
            {
                return y;
            }
            set
            {
                y = value;
            }
        }
        public Location():this(0,0)
        {
        }
        public Location(double theX, double theY)
        {
            X = theX;
            Y = theY;
        }
        public Location(XElement element)
        {
            FromXElement(element);
        }
        public IHeading ToHeading()
        {
            return new Heading(Math.Atan2(Y, X) * 180.0 / Math.PI);
        }
        private void FromXElement(XElement element)
        {
            X = Utilities.XElementToDouble(element.Element(GameXNames.x));
            Y = Utilities.XElementToDouble(element.Element(GameXNames.y));
        }
        public XElement ToXElement(XName xName)
        {
            XElement result = new XElement(xName,
                new XElement(GameXNames.x, x.ToString()),
                new XElement(GameXNames.y, y.ToString()));
            return result;
        }
        public double DistanceTo(ILocation other)
        {
            return Distance(this, other);
        }
        public static double Distance(ILocation first, ILocation second)
        {
            double deltaX = first.X - second.X;
            double deltaY = first.Y - second.Y;
            return Math.Sqrt(deltaX*deltaX + deltaY*deltaY);
        }
        public ILocation MidpointWith(ILocation other)
        {
            return Midpoint(this, other);
        }
        public static Location Midpoint(ILocation first, ILocation second)
        {
            return new Location(first.X / 2 + second.X / 2, first.Y / 2 + second.Y / 2);
        }
        public double Magnitude
        {
            get
            {
                return DistanceTo(new Location());
            }
        }
    }
}
